Network routers for packet-based communications protocols such as Internet Protocol (IP) direct incoming information to the next neighbor along a route to the intended destination for the packet. To do this, typically each router along the route performs route address prefix (normally referred to as just “prefix”) look-up operations on a prefix (or routing) table to determine the appropriate next hop address for the destination IP prefix. Such operations are generally performed by either an embedded network processor or, more commonly, a separate network search engine.
Originally the hardware for network search engines employed content addressable memory (CAM), a type of memory consisting of a bit comparator and two memory elements, one storing data and the other storing a compare mask. The CAM compares incoming data with the value stored in the data memory under the control of the mask value, which may be programmed to override the comparison result to “always match”. In operation, a CAM-based network search engine functions by storing all prefixes of a routing table in a CAM array in a specific, prioritized order, with each prefix's associated next hop information stored in a corresponding location in another memory. During prefix look-up, a key is placed on the comparand (compare operand) bus of the CAM array and compared against all prefixes in the memory. The array of match results from all comparisons is sent through a priority logic unit to determine the highest priority match, with the winning match used to address the next hop memory from which the corresponding next hop information is read and returned.
More recently, software-based network search engines employing a general-purpose processor and a normal memory have been developed. Within such devices, the processor performs prefix searches with a series of memory read and comparison operations. The routing table prefixes and next hop information are typically stored in the memory in data structures built according to one of various software algorithms developed to reduce memory usage in storing the routing table and the number of memory accesses during look-up. For these purposes, a multi-bit trie and the corresponding algorithm are among the data structures and algorithms that achieve the best data compression with a bounded number of memory accesses for search operations.
A trie is a tree-based data structure built to represent binary strings, where each bit or group of bits in the string determines the direction taken among branches within the tree. A binary trie proceeds bit-by-bit and has at most two branches from each node, while a multi-bit trie consumes multiple bits at a time and has several branches at each node, each branch leading to the next level. The number of bits consumed or examined during branch selection at each node is referred to as a stride. A uniform width stride trie is a trie with all strides having the same width, except possibly the last stride, which may be the remainder of the prefix length after being divided by the stride width.
Generally, the multi-bit trie algorithm works by storing and retrieving prefixes in a uniform stride width trie, grouping all branches in the same level with the same parent stride value into a table, referred to as a trie table. At each level, the corresponding stride value provides an index into a trie table entry containing the information needed to get to the next level. A multi-bit trie has the advantage that prefixes with common high order bits (strides) will share the same parent trie tables, reducing the memory required to store the prefixes.
Routing table look-up is also performed in same width strides, with the value of the next level stride from the input search key (typically an IP address of 32 or 64 bits) decoded and processed together with the associated data field in the stride value's parent table entry. If a stored route with the same prefix stride value is determined to exist within the trie, an index is calculated using the information in the parent table, then the search continues using the table pointer and the calculated index to form an address leading to the next level trie table entry. If a match is not found, the search terminates without success. If a search reaches an end node and a match is found, the search is successful and the associated next hop information is read from the next hop table.
In conventional processing systems that operate as described above, multiple stored prefixes may match a single destination address that is used as the search key during a look-up operation. This is due to the fact that any n-bit prefix is defined to match the search key even if the search key is longer than the prefix, provided the complete n-bit prefix matches the first n bits of the search key. Thus, for example, a 2-bit prefix and a 16-bit prefix may both match a 32-bit search key if the 2-bit prefix matches the first two bits of the search key and the 16-bit prefix matches the first sixteen bits of the search key. In order to resolve multiple matches, therefore, the search engine selects only the data associated with the longest matching prefix when responding to the look-up operation.
However, selecting between multiple matches in this way fails to address the problem of matches found within multiple search engines. Continuing the above example, if the 2-bit prefix was in a first search engine and the 16-bit prefix was in a second search engine, both search engines would respond to the look-up operation, creating a conflict.
Current processing systems with multiple search engines solve this problem by requiring the network processor to perform separate searches within each search engine and then to determine which of the multiple responses to accept. However, this solution is unsatisfactory as it results in a significant increase in look-up time.